package com.ruoyi.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;

@Slf4j
public class ImageUtils {

	/**
	 * 通过BufferedImage图片流调整图片大小
	 * 指定压缩后长宽
	 */
	public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) throws IOException {
		Image resultingImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_AREA_AVERAGING);
		BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
		outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
		return outputImage;
	}

	/**
	 * 通过BufferedImage图片流调整图片大小
	 * @param originalImage
	 * @param reduceMultiple 缩小倍数
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage resizeImage(BufferedImage originalImage, float reduceMultiple) throws IOException {
		int width = (int) (originalImage.getWidth() * reduceMultiple);
		int height = (int) (originalImage.getHeight() * reduceMultiple);
		Image resultingImage = originalImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
		BufferedImage outputImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		outputImage.getGraphics().drawImage(resultingImage, 0, 0, null);
		return outputImage;
	}

	/**
	 * 压缩图片到指定大小
	 * @param srcImgData
	 * @param reduceMultiple 每次压缩比率
	 * @return
	 * @throws IOException
	 */

	public static byte[] resizeImage(byte[] srcImgData, float reduceMultiple) throws IOException {
		BufferedImage bi = ImageIO.read(new ByteArrayInputStream(srcImgData));
		int width = (int) (bi.getWidth() * reduceMultiple); // 源图宽度
		int height = (int) (bi.getHeight() * reduceMultiple); // 源图高度
		Image image = bi.getScaledInstance(width, height, Image.SCALE_SMOOTH);
		BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g = tag.getGraphics();
		g.setColor(Color.RED);
		g.drawImage(image, 0, 0, null); // 绘制处理后的图
		g.dispose();
		ByteArrayOutputStream bOut = new ByteArrayOutputStream();
		ImageIO.write(tag, "JPEG", bOut);
		return bOut.toByteArray();
	}


	/**
	 * BufferedImage图片流转byte[]数组
	 */
	public static byte[] imageToBytes(BufferedImage bImage) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			ImageIO.write(bImage, "jpg", out);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return out.toByteArray();
	}


	/**
	 * byte[]数组转BufferedImage图片流
	 */
	private static BufferedImage bytesToBufferedImage(byte[] ImageByte) {
		ByteArrayInputStream in = new ByteArrayInputStream(ImageByte);
		BufferedImage image = null;
		try {
			image = ImageIO.read(in);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return image;
	}

	/**
	 * 判断文件大小处于限制内
	 *
	 * @param fileLen 文件长度
	 * @param fileSize 限制大小
	 * @param fileUnit 限制的单位（B,K,M,G）
	 * @return
	 */
	public static boolean checkFileSizeIsLimit(Long fileLen, int fileSize, String fileUnit) {
//        long len = file.length();
		double fileSizeCom = 0;
		if ("B".equals(fileUnit.toUpperCase())) {
			fileSizeCom = (double) fileLen;
		} else if ("K".equals(fileUnit.toUpperCase())) {
			fileSizeCom = (double) fileLen / 1024;
		} else if ("M".equals(fileUnit.toUpperCase())) {
			fileSizeCom = (double) fileLen / (1024*1024);
		} else if ("G".equals(fileUnit.toUpperCase())) {
			fileSizeCom = (double) fileLen / (1024*1024*1024);
		}
		if (fileSizeCom > fileSize) {
			return false;
		}
		return true;

	}


	/**
	 * file转multipartFile
	 * @param file
	 * @return
	 */
	public static MultipartFile fileToMultipartFile(File file) {
		log.info("fileToMultipartFile文件转换中："+file.getAbsolutePath());
		FileItemFactory factory = new DiskFileItemFactory(16, null);
		FileItem item=factory.createItem(file.getName(),"text/plain",true,file.getName());
		int bytesRead = 0;
		byte[] buffer = new byte[8192];
		try {
			FileInputStream fis = new FileInputStream(file);
			OutputStream os = item.getOutputStream();
			while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
			}
			os.close();
			fis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new CommonsMultipartFile(item);
	}



	public static String getFileSuffix(File file) {
		if (file == null) {
			return null;
		}
		String suffix = null;
		String fileName = file.getName();
		if (fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0) {
			suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
		}
		return suffix;
	}    //
	public static boolean isImage(File file) {
		boolean result = false;
		//是否是图片
		String imgs = "JPEG,JPG,PNG";

		if (imgs.contains(getFileSuffix(file).toUpperCase())) {
			result = true;
		}
		return result;
	}





	/**
	 * 保存照片文件
	 *
	 * @param path 文件绝对路径
	 */
	public static void saveFile(String path){
		try {
			File fileInit = new File(path);
			if (fileInit.exists()){
				MultipartFile file =fileToMultipartFile(fileInit);
				log.info("file转multipartFile成功. {}", file);
				if (!checkFileSizeIsLimit(file.getSize(),200,"K")){
					if (file != null && !file.isEmpty()) {
						//保存文件到对应位置
						File dir = new File(path);
						if (!dir.getParentFile().exists()) {
							dir.getParentFile().mkdirs();
						}
						// 压缩到小于指定文件大小400k
						double targetSize = 400 * 1024;

						//从MultipartFile 中获取 byte[]
						byte[] bytes = file.getBytes();
						log.info("头像图片压缩前大小：[{}]", bytes.length);
						while (bytes.length > targetSize) {
							float reduceMultiple = 0.5f;
							bytes = resizeImage(bytes, reduceMultiple);
						}
						log.info("头像图片压缩后大小：[{}]", bytes.length);
						BufferedImage newImage = bytesToBufferedImage(bytes);
						//图像缓冲区图片保存为图片文件(文件不存在会自动创建文件保存，文件存在会覆盖原文件保存)
						ImageIO.write(newImage, "jpg", new File(path));

					}
				}
			}
		} catch (IOException e) {
			//抛出异常
			log.info("图片压缩出错");
		}
	}


	public void covert(String url) {
		File file = new File(url);
//		File file = new File(SysConfig.getProfile());
		fileDird(file);
	}

	/**
	 * 遍历指定文件下的所有文件，包括目录中的文件
	 */
	public static void fileDird(File file) {
		File[] fs = file.listFiles();
		for (File f : fs) {
			if (f.isDirectory()) {
				//若是目录，则递归打印该目录下的文件
				fileDird(f);
			} else if (f.isFile() && isImage(f)) {        //若是图片文件
				log.info(f.getAbsolutePath());
				//若是文件则进行压缩
				saveFile(f.getAbsolutePath());
			}
		}
	}

	public static void main(String args[]){
		File file = new File("G:\\交接资料\\营业执照\\aaa");
		fileDird(file);
	}
}